package com.pajx.testopengles.util

import android.content.Context
import android.graphics.Bitmap
import android.graphics.BitmapFactory
import android.opengl.GLES20
import android.opengl.GLUtils
import android.util.Log
import java.io.ByteArrayOutputStream
import java.io.InputStream
import java.nio.ByteBuffer
import java.nio.ByteOrder
import java.nio.FloatBuffer
import java.nio.ShortBuffer
import java.nio.charset.StandardCharsets

/**
 *User: RandBII
 *Date: 2020/8/11
 *Description: ShaderHelp 的方法都移动到了 此类中，封装了常用的方法
 */

object GLHelper {

    fun getFloatBuffer(vertex: FloatArray): FloatBuffer {
        return ByteBuffer.allocateDirect(vertex.size * 4).order(ByteOrder.nativeOrder())
            .asFloatBuffer()
            .apply {
                put(vertex)
                position(0)
            }
    }

    fun getShortBuffer(vertex: ShortArray): ShortBuffer {
        return ByteBuffer.allocateDirect(vertex.size * 2).order(ByteOrder.nativeOrder())
            .asShortBuffer()
            .apply {
                put(vertex)
                position(0)
            }
    }

    fun loadShader(type: Int, shaderCode: String): Int {
        val shaderInt = GLES20.glCreateShader(type)
        GLES20.glShaderSource(shaderInt, shaderCode)
        GLES20.glCompileShader(shaderInt)
        checkShaderCompile(type, shaderInt)
        return shaderInt
    }


    fun loadShaderAsserts(context: Context, name: String): String {

        var input: InputStream? = null
        var bos: ByteArrayOutputStream? = null
        var buffer: ByteArray? = null
        try {
            input = context.resources.assets.open(name)
            bos = ByteArrayOutputStream()
            var aa: Int = 0
            while (input.read().also { aa = it } != -1) {
                bos.write(aa)
            }

            buffer = bos.toByteArray()
            return String(buffer, StandardCharsets.UTF_8).also {
                it.replace("\\r\\n", "\n")
            }


        } catch (e: Exception) {
            e.printStackTrace()
            return ""
        } finally {
            input?.close()
            bos?.close()

        }

    }


    private fun checkShaderCompile(type: Int, shaderId: Int): Int {

        val status = IntArray(1)

        GLES20.glGetShaderiv(shaderId, GLES20.GL_SHADER_COMPILER, status, 0)
        if (status[0] <= 0) {
            Log.e("-->", "shaderCompile erro--> ${GLES20.glGetShaderInfoLog(shaderId)}")
            return 0
        }

        return shaderId
    }


    fun validateProgram(program: Int) {
        GLES20.glValidateProgram(program)
        val validateStatus: IntArray = IntArray(1)
        GLES20.glGetProgramiv(program, GLES20.GL_VALIDATE_STATUS, validateStatus, 0)
        Log.e(
            "-->",
            "program validate-->status =${validateStatus[0]}  info=  ${GLES20.glGetProgramInfoLog(
                program
            )}"
        )
        if (validateStatus[0] <= 0) {
            Log.e(
                "-->",
                "program validate-->status =${validateStatus[0]}  info=  ${GLES20.glGetProgramInfoLog(
                    program
                )}"
            )
            GLES20.glDeleteProgram(program)
        }

    }

    fun loadTexture(ctx: Context, resId: Int): Int {

        val b = BitmapFactory.decodeResource(ctx.resources, resId)
        Log.e("-->", "in  loadTexture bitmap ==${b}")
        return loadTexture(ctx, b)

    }


    fun loadTexture(ctx: Context, bitmap: Bitmap): Int {

        Log.e("-->", " out loadTexture bitmap    ==${bitmap}")
        val textures = IntArray(1)
        GLES20.glGenTextures(1, textures, 0)
        val textureId = textures[0]
        GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textureId)
        GLES20.glTexParameterf(
            GLES20.GL_TEXTURE_2D,
            GLES20.GL_TEXTURE_MIN_FILTER,
            GLES20.GL_NEAREST.toFloat()
        )
        GLES20.glTexParameterf(
            GLES20.GL_TEXTURE_2D,
            GLES20.GL_TEXTURE_MAG_FILTER,
            GLES20.GL_LINEAR.toFloat()
        )
        GLES20.glTexParameterf(
            GLES20.GL_TEXTURE_2D,
            GLES20.GL_TEXTURE_WRAP_S,
            GLES20.GL_CLAMP_TO_EDGE.toFloat()
        )
        GLES20.glTexParameterf(
            GLES20.GL_TEXTURE_2D,
            GLES20.GL_TEXTURE_WRAP_T,
            GLES20.GL_CLAMP_TO_EDGE.toFloat()
        )
        GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, 0, bitmap, 0)
        bitmap?.recycle()
        return textureId

    }

}